package com.plat.api.api.action;

import java.util.Date;

import java.math.BigDecimal;

import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.collect.Lists;

import com.alibaba.fastjson.JSONObject;
import com.plat.api.anonation.Token;
import com.plat.api.api.action.common.UserInfo;
import com.plat.api.common.OrderType;
import com.plat.api.common.RespCode;
import com.plat.api.dao.api.*;
import com.plat.api.entity.RepGoodsInfo;
import com.plat.api.entity.api.*;
import com.plat.api.exception.PlatException;
import com.plat.api.util.SnowflakeIdWorker;
import com.plat.api.util.StringUtil;
import com.plat.api.util.YmalPropertiesUtil;
import com.plat.common.utils.StringUtils;
import com.plat.framework.redis.RedisCache;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * author ss
 * createTime 2020/5/8
 * package ${com.example.demo.controller.action}
 ***/
@Component
@Token
public class OrderAction {
    @Autowired
    private PlatOrderDao orderDao;
    @Autowired
    private PlatOrderDetailDao detailDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private TokenDao tokenDao;
    @Autowired
    private PlatVideoDao platVideoDao;
    @Autowired
    private PlatAuctionDao platAuctionDao;
    @Autowired
    private PlatAddressDao platAddressDao;
    @Autowired
    private PlatExpressInfoDao platExpressInfoDao;
    @Autowired
    private PlatRefundApplyDao refundApplyDao;
    @Autowired
    private WxPayService wxService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 再次发起支付
     */
    public JSONObject rePay(JSONObject jsonObject) throws WxPayException {
        JSONObject body = jsonObject.getJSONObject("body");
        String orderNo = body.getString("orderNo");
        String payBody = body.getString("payBody");
        UserEntity userEntity = UserInfo.getUserEntity(jsonObject, userDao, tokenDao);
        PlatOrderEntity platOrderEntity = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId())
                .andEq("pay_status", 0).andEq("express_status", OrderType.ORDER_EXPRESS_NO_DISTRIBUTE).andEq("order_no", orderNo).single();
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        String outTradeNo = SnowflakeIdWorker.getId();
        request.setOpenid(userEntity.getOpenId());
        request.setBody(payBody);
        request.setOutTradeNo(outTradeNo);
        request.setTotalFee(platOrderEntity.getOrderPrice().intValue());
        request.setSpbillCreateIp("0.0.0.0");
        request.setNotifyUrl(YmalPropertiesUtil.getValue("wxpay.notify-url").toString());
        request.setTradeType("JSAPI");
        WxPayMpOrderResult wxPayMpOrderResult = wxService.createOrder(request);
        if (wxPayMpOrderResult != null) {
            redisCache.setCacheObject(outTradeNo, outTradeNo);
        } else {
            throw new PlatException(RespCode.CREATE_ORDER_FAIL.getCode(), "微信支付创建订单失败", RespCode.CREATE_ORDER_FAIL.getError_msg(), RespCode.CREATE_ORDER_FAIL.getError_msg());
        }
        JSONObject json = new JSONObject();
        json.put("payInfo", wxPayMpOrderResult);
        return json;
    }


    /**
     * 查询订单的通用接口
     */
    public JSONObject orderList(JSONObject jsonObject) {
        JSONObject body = jsonObject.getJSONObject("body");
        Integer page = body.getInteger("page");
        Integer pageSize = body.getInteger("pageSize");
        Integer type = body.getInteger("type");
        if (type == null) {
            type = 0;
        }
        UserEntity userEntity = UserInfo.getUserEntity(jsonObject, userDao, tokenDao);
        LambdaQuery<PlatOrderEntity> lambdaQuery = null;
        //全部
        if (type == 0) {
            lambdaQuery = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId());
        }
        //待支付
        if (type == 1) {
            lambdaQuery = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId()).andEq("pay_status", 0);
        }
        //待发货
        if (type == 2) {
            lambdaQuery = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId())
                    .andEq("pay_status", 1).andEq("express_status", OrderType.ORDER_EXPRESS_NO_DISTRIBUTE);
        }
        //待收货
        if (type == 3) {
            lambdaQuery = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId())
                    .andEq("pay_status", 1).andEq("express_status", OrderType.ORDER_EXPRESS_DISTRIBUTE);
        }
        //完成
        if (type == 4) {
            lambdaQuery = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId())
                    .andEq("pay_status", 1).andEq("order_status", OrderType.ORDER_FINISH);
        }
        PageQuery<PlatOrderEntity> pageQuery = lambdaQuery.page(page, pageSize);
        List<PlatOrderEntity> list = pageQuery.getList();
        List<RepOrderDetail> reList = new ArrayList<>();
        for (PlatOrderEntity order : list) {
            RepOrderDetail orderDetail = new RepOrderDetail();
            PlatOrderDetailEntity detailEntity = detailDao.createLambdaQuery().andEq("order_no", order.getOrderNo()).single();
            if (detailEntity != null) {
                orderDetail.setOrderNo(order.getOrderNo());
                orderDetail.setStatus(order.getOrderStatus());
                if (order.getPayStatus() == 1) {
                    orderDetail.setPayStatus(1);
                    orderDetail.setOrderStatus("已支付");
                } else {
                    orderDetail.setOrderStatus("未支付");
                    orderDetail.setPayStatus(0);
                }
                if (order.getOrderType().equals(OrderType.AUCTION)) {
                    AuctionEntity auctionEntity = platAuctionDao.createLambdaQuery().andEq("id", detailEntity.getGoodsId()).single();
                    RepGoodsInfo repGoodsInfo = new RepGoodsInfo();
                    repGoodsInfo.setName(auctionEntity.getName());
                    repGoodsInfo.setImage(StringUtil.solveString(auctionEntity.getUrl()).split(",")[0]);
                    repGoodsInfo.setMoney(new BigDecimal(String.valueOf(order.getOrderPrice())));
                    List<RepGoodsInfo> li = new ArrayList<>();
                    li.add(repGoodsInfo);
                    orderDetail.setGoodsList(li);
                } else {
                    PlatVideoEntity platVideoEntity = platVideoDao.createLambdaQuery().andEq("id", detailEntity.getGoodsId()).single();

                    RepGoodsInfo repGoodsInfo = new RepGoodsInfo();
                    repGoodsInfo.setName(platVideoEntity.getVideoName());
                    repGoodsInfo.setImage(StringUtil.solveString(platVideoEntity.getPoster()));
                    repGoodsInfo.setMoney(new BigDecimal(String.valueOf(order.getOrderPrice())));
                    List<RepGoodsInfo> li = new ArrayList<>();
                    li.add(repGoodsInfo);
                    orderDetail.setGoodsList(li);
                }
                orderDetail.setCount(1);
                orderDetail.setCountMoney(order.getOrderPrice());
            }
            if (orderDetail.getOrderNo() != null) {
                reList.add(orderDetail);
            }

        }
        JSONObject json = new JSONObject();
        json.put("list", reList);
        return json;
    }

    public JSONObject orderDetail(JSONObject jsonObject) {
        JSONObject body = jsonObject.getJSONObject("body");
        Integer id = body.getInteger("id");
        PlatOrderEntity order = orderDao.createLambdaQuery().andEq("id", id).single();
        PlatOrderDetailEntity detailEntity = detailDao.createLambdaQuery().andEq("order_no", order.getOrderNo()).single();
        PlatExpressInfoEntity platExpressInfoEntity = platExpressInfoDao.createLambdaQuery().andEq("order_no", order.getOrderNo()).single();
        RepOrderDetail orderDetail = new RepOrderDetail();
        Map<String, Object> result = new HashMap<>();
        if (order.getOrderType().equals(OrderType.AUCTION)) {
            AuctionEntity auctionEntity = platAuctionDao.createLambdaQuery().andEq("id", detailEntity.getGoodsId()).single();
            result.put("name", auctionEntity.getName());
            result.put("price", order.getOrderPrice());
            result.put("createTime", order.getCreateTime());
            result.put("couuponPirce", 0);
            result.put("payTime", order.getPayTime());
            result.put("refundTime", null);
        } else {
            PlatVideoEntity platVideoEntity = platVideoDao.createLambdaQuery().andEq("id", detailEntity.getGoodsId()).single();
            result.put("name", platVideoEntity.getVideoName());
            result.put("price", order.getOrderPrice());
            result.put("createTime", order.getCreateTime());
            result.put("couuponPirce", 0);
            result.put("payTime", order.getPayTime());
            result.put("refundTime", null);
        }
        JSONObject json = new JSONObject();
        json.put("object", result);
        return json;
    }

    /**
     * 退款申请
     */
    public JSONObject refundApply(JSONObject jsonObject) {
        JSONObject body = jsonObject.getJSONObject("body");
        String orderNo = body.getString("orderNo");
        String refundMsg = body.getString("refundMsg");
        UserEntity userEntity = UserInfo.getUserEntity(jsonObject, userDao, tokenDao);
        PlatOrderEntity platOrderEntity = orderDao.createLambdaQuery().andEq("user_id", userEntity.getId())
                .andEq("pay_status", 1).andEq("express_status", OrderType.ORDER_EXPRESS_NO_DISTRIBUTE).andEq("order_no", orderNo).single();
        if (platOrderEntity != null) {
            PlatRefundApplyEntity apply = new PlatRefundApplyEntity();
            apply.setMainOrder(orderNo);
            apply.setRefundOrder("");
            apply.setCreateTime(new Date());
            apply.setRefundAmt(platOrderEntity.getOrderPrice().doubleValue());
            apply.setRefundRealAmt(0.0D);
            apply.setFinishTime(new Date());
            apply.setRefundStatus(OrderType.ORDER_REFUND_WAITING);
            apply.setRefundMsg(refundMsg);
            apply.setUserId(userEntity.getId());
            apply.setApplyName(userEntity.getName());
            refundApplyDao.insert(apply);
            platOrderEntity.setRefundStatus(OrderType.ORDER_REFUND_WAITING);
            orderDao.updateById(platOrderEntity);
        } else {
            throw new PlatException("退款申请，请申请售后服务！！！");
        }
        JSONObject json = new JSONObject();
        json.put("msg", "申请中");
        return json;
    }
}
